From 90dfddafb52e7a6d9447244700421b4762de0076 Mon Sep 17 00:00:00 2001 From: Alastair Tse Date: Thu, 16 Nov 2006 13:49:05 +0000 Subject: [PATCH] [XEND] Fix PCI configuration parsing and SXP output PCI configuration is formatted differently from other device configurations because of the requirement that all pci devices need to be present when it is initialised. Signed-off-by: Alastair Tse --- tools/python/xen/xend/XendConfig.py | 76 +++++++++++++++++++++++++-- tools/python/xen/xend/server/pciif.py | 22 ++++---- 2 files changed, 83 insertions(+), 15 deletions(-) diff --git a/tools/python/xen/xend/XendConfig.py b/tools/python/xen/xend/XendConfig.py index 93ad4b6598..2d86122428 100644 --- a/tools/python/xen/xend/XendConfig.py +++ b/tools/python/xen/xend/XendConfig.py @@ -17,6 +17,7 @@ import re import time +import types from xen.xend import sxp from xen.xend import uuid @@ -450,11 +451,36 @@ class XendConfig(dict): for c in sxp.children(parsed, 'backend'): cfg['backend'].append(sxp.name(sxp.child0(c))) + # Parsing the device SXP's. In most cases, the SXP looks + # like this: + # + # [device, [vif, [mac, xx:xx:xx:xx:xx:xx], [ip 1.3.4.5]]] + # + # However, for PCI devices it looks like this: + # + # [device, [pci, [dev, [domain, 0], [bus, 0], [slot, 1]]]] + # + # It seems the reasoning for this difference is because + # pciif.py needs all the PCI device configurations at + # the same time when creating the devices. + # + # To further complicate matters, Xen 2.0 configuration format + # uses the following for pci device configuration: + # + # [device, [pci, [domain, 0], [bus, 0], [dev, 1], [func, 2]]] + # + # Hence we deal with pci device configurations outside of + # the regular device parsing. + cfg['device'] = {} for dev in sxp.children(parsed, 'device'): config = sxp.child0(dev) dev_type = sxp.name(config) dev_info = {} + + if dev_type == 'pci': + continue + for opt, val in config[1:]: dev_info[opt] = val log.debug("XendConfig: reading device: %s" % dev_info) @@ -462,9 +488,34 @@ class XendConfig(dict): dev_uuid = dev_info.get('uuid', uuid.createString()) dev_info['uuid'] = dev_uuid cfg['device'][dev_uuid] = (dev_type, dev_info) - - #cfg['device'].append((sxp.name(config), config)) + # deal with PCI device configurations if they exist + for dev in sxp.children(parsed, 'device'): + config = sxp.child0(dev) + dev_type = sxp.name(config) + + if dev_type != 'pci': + continue + + dev_attr = sxp.child_value(config, 'dev') + if isinstance(dev_attr, (types.ListType, types.TupleType)): + for pci_dev in sxp.children(config, 'dev'): + dev_info = {} + for opt, val in pci_dev[1:]: + dev_info[opt] = val + log.debug("XendConfig: reading device: %s" % dev_info) + dev_uuid = dev_info.get('uuid', uuid.createString()) + dev_info['uuid'] = dev_uuid + cfg['device'][dev_uuid] = (dev_type, dev_info) + + else: # Xen 2.0 PCI device configuration + for opt, val in config[1:]: + dev_info[opt] = val + log.debug("XendConfig: reading device: %s" % dev_info) + # create uuid if it doesn't + dev_uuid = dev_info.get('uuid', uuid.createString()) + dev_info['uuid'] = dev_uuid + cfg['device'][dev_uuid] = (dev_type, dev_info) # Extract missing data from configuration entries if 'image' in cfg: @@ -859,10 +910,27 @@ class XendConfig(dict): return sxpr def all_devices_sxpr(self): + """Returns the SXPR for all devices in the current configuration.""" sxprs = [] + pci_devs = [] for dev_type, dev_info in self['device'].values(): - sxpr = self.device_sxpr(dev_type = dev_type, dev_info = dev_info) - sxprs.append((dev_type, sxpr)) + if dev_type == 'pci': # special case for pci devices + pci_devs.append(dev_info) + else: + sxpr = self.device_sxpr(dev_type = dev_type, + dev_info = dev_info) + sxprs.append((dev_type, sxpr)) + + # if we have any pci_devs, we parse them differently into + # one single pci SXP entry. + if pci_devs: + sxpr = ['pci',] + for dev_info in pci_devs: + dev_sxpr = self.device_sxpr(dev_type = 'dev', + dev_info = dev_info) + sxpr.append(dev_sxpr) + sxprs.append(('pci', sxpr)) + return sxprs diff --git a/tools/python/xen/xend/server/pciif.py b/tools/python/xen/xend/server/pciif.py index aa7f3c8c98..eaab90529f 100644 --- a/tools/python/xen/xend/server/pciif.py +++ b/tools/python/xen/xend/server/pciif.py @@ -65,7 +65,7 @@ class PciController(DevController): else: return default - if isinstance(val, types.StringType): + if isinstance(val, types.StringTypes): return int(val, 16) else: return val @@ -79,7 +79,7 @@ class PciController(DevController): back = {} val = sxp.child_value(config, 'dev') - if isinstance(val, list): + if isinstance(val, (types.ListType, types.TupleType)): pcidevid = 0 for dev_config in sxp.children(config, 'dev'): domain = get_param(dev_config, 'domain', 0) @@ -89,7 +89,7 @@ class PciController(DevController): self.setupDevice(domain, bus, slot, func) - back['dev-%i'%(pcidevid)]="%04x:%02x:%02x.%02x"% \ + back['dev-%i' % pcidevid]="%04x:%02x:%02x.%02x"% \ (domain, bus, slot, func) pcidevid+=1 @@ -115,19 +115,19 @@ class PciController(DevController): pci_devs = [] for i in range(int(num_devs)): - (dev_config,) = self.readBackend(devid, 'dev-%d'%(i)) + dev_config = self.readBackend(devid, 'dev-%d' % i) - pci_match = re.match(r"((?P[0-9a-fA-F]{1,4})[:,])?" + \ - r"(?P[0-9a-fA-F]{1,2})[:,]" + \ - r"(?P[0-9a-fA-F]{1,2})[.,]" + \ - r"(?P[0-9a-fA-F]{1,2})", dev_config) + pci_match = re.match(r"((?P[0-9a-fA-F]{1,4})[:,])?" + + r"(?P[0-9a-fA-F]{1,2})[:,]" + + r"(?P[0-9a-fA-F]{1,2})[.,]" + + r"(?P[0-9a-fA-F]{1,2})", dev_config) if pci_match!=None: - pci_dev_info = pci_match.groupdict('0') + pci_dev_info = pci_match.groupdict() pci_devs.append({'domain': '0x%(domain)s' % pci_dev_info, 'bus': '0x%(bus)s' % pci_dev_info, - 'slot': '0x(slot)s' % pci_dev_info, - 'func': '0x(func)s' % pci_dev_info}) + 'slot': '0x%(slot)s' % pci_dev_info, + 'func': '0x%(func)s' % pci_dev_info}) result['dev'] = pci_devs return result -- 2.30.2